package com.distribute.framework.core.lsf;

import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;

import com.distribute.framework.core.lsf.entity.AppInfo;
import com.distribute.framework.core.lsf.protocol.ILsfManager;
import com.distribute.framework.core.web.helper.Utils;
import com.distribute.framework.core.web.helper.SpringBeanHelper;

public class LsfProvider extends Thread implements InitializingBean,FactoryBean{
	
	private Lsf lsf = null;
	private ILsfManager manager = null;
	static Set<String> regists = new HashSet();
	static Map<String,String> interface_bean_mapping = new HashMap();
	
	public LsfProvider(){
		
	}
	public void afterPropertiesSet() throws Exception {
		manager = new LsfRedisManager(lsf);
		for(String beanName:lsf.getBeans()){
			Object bean = Utils.getBean(beanName);
			if(bean==null)
				throw new LsfException("<lsf> - 无法根据["+beanName+"]获取对象");
			Class<?> targetClass = bean.getClass();
			String serviceInterface = targetClass.getInterfaces()[0].getName();
			interface_bean_mapping.put(serviceInterface, beanName);
			lsf.serverServerInfo.getInterfaces().add(serviceInterface);
		}
		Utils.trace("<lsf> - services:"+lsf.getBeans());
		this.start();
	}
	public Object getObject() throws Exception {
		return this;
	}
	public Class getObjectType() {
		return LsfProvider.class;
	}

	public boolean isSingleton() {
		return false;
	}
	
	@Override
	public void run() {
		while(true){
			try {
				regist();
			} catch (Exception e) {
				e.printStackTrace();
			}
			try {
				Thread.sleep(30000l);
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}
	
	//向管理中心注册本服务
	public void regist() {
		if(lsf.serverServerInfo==null)
			return;
		Utils.trace("<lsf> - 注册返回 - "+manager.regist(lsf.serverServerInfo));
	}


	/**
	 * 消费者远程调用本服务
	 * @param clientId
	 * @param visitKey
	 * @param serviceInterface
	 * @param methodName
	 * @param params
	 * @return
	 */
	public Object invoker(String visitKey,String serviceInterface, String methodName, Object[] args) throws Exception {
		//根据接口名称获取bean
		String beanName = interface_bean_mapping.get(serviceInterface);
		//Utils.trace("消费者远程调用本服务",serviceInterface,methodName,beanName);
		if(beanName==null)
			throw new LsfException("<lsf> - 无法根据接口<"+serviceInterface+">获取bean");
		Object bean = Utils.getBean(beanName);
		for(Method method:bean.getClass().getMethods()){
			if(method.getName().equals(methodName) && method.getParameterTypes().length==args.length){
				return method.invoke(bean, args);
			}
		}
		for(Method method:bean.getClass().getMethods()){
			Utils.trace(method.getName(),(methodName));
		}
		//Utils.trace(bean.getClass().getName());
		throw new NoSuchMethodException("<lsf> - 无法根据接口<"+serviceInterface+">找到调用函数:"+methodName);
	}
	public Lsf getLsf() {
		return lsf;
	}
	public void setLsf(Lsf lsf) {
		this.lsf = lsf;
	}
	
}